﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
using System;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using System.IO;
using System.Collections.Generic;
using MvvmLight1.ServiceReference1;
using System.Windows.Media.Animation;
using System.Security.AccessControl;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media;

namespace MvvmLight1.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        #region Data Members

        private static readonly ServiceReference1.Service1Client proxy;
        private List<MyBannerClass> banners;
        private List<double> bannersTimeLine;
        private int bannerTime;
        private const int MAXBANNERS = 5;
        private int currentTimeLine;
        private int currentVideoId;

        #endregion

        #region Constractors

        /// <summary>
        /// Initializes a new instance of the static proxy. 
        /// </summary>
        static MainViewModel()
        {
            if (ViewModelBase.IsInDesignModeStatic) return;

            proxy = new Service1Client();
        }

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            if (ViewModelBase.IsInDesignModeStatic) return;

            PlayPauseButtonContent = "";
            StopButtonContent = "";
            MediaVolume = 0.5;
            SoundImageSource = "Images\\Sound.png";
            TagImageSound = "1";
            BannerVisibility = Visibility.Hidden;
            MyVideoPath = null;
            MediaHeight = 350;
            //CircularProgressBarVisibility = Visibility.Hidden;
            BannerHeight = 0;
            VideoStatus = PlayerStatus.Stop;
            OpenDialogBox = new RelayCommand(openDlg);
            this.CanCommandExecute = true;

            ImageCommand = new RelayCommand<ListViewItem>(ShowVideoCommand);
            SetStatusCommand = new RelayCommand<object>(SetStatus);
            HeightCommand = new RelayCommand<double>(MediaElementHeightChangedCommand);
            WidthCommand = new RelayCommand<double>(MediaElementWidthChangedCommand);
            SoundImageCommand = new RelayCommand<string>(SetSoundImageSource);

            GetAllVideoThumbnails();
            bannersTimeLine = new List<double>();
            banners = new List<MyBannerClass>();
            currentTimeLine = 0;
            currentVideoId = -1;
        }

        #endregion

        #region ProcessBanner

        public void ProcessBanner(double rang)
        {
            if (currentTimeLine == bannersTimeLine.Count)
                return;

            if (bannersTimeLine[currentTimeLine] <= rang)
            {
                //bannersTimeLine.RemoveAt(0);
                var b = banners[currentTimeLine];
                //banners.RemoveAt(0);

                //BannerContent = b.bannerContent;
                BannerImage = b.bannerUrl;//GetBitmapImage(b.bannerUrl);
                BannerHeight = b.bannerSize;
                bannerTime = b.bannerTime;
                BannerVisibility = Visibility.Visible;

                new Thread(() =>
                {
                    Thread.Sleep(bannerTime * 1000);
                    BannerVisibility = Visibility.Hidden;
                }).Start();

                currentTimeLine++;
            }
        }

        void bw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            Thread.Sleep(bannerTime * 1000);
            BannerVisibility = Visibility.Hidden;
        }

        public void OrganizeBannersTimeLine(double totalRang)
        {
            if (banners.Count == 0) return;

            new Thread(() =>
            {
                bannersTimeLine.Clear();
                currentTimeLine = 0;

                // setting the time lines of the banners
                var numB = banners.Count > 5 ? MAXBANNERS : banners.Count;
                var numBDRang = (int)((totalRang - 10) / numB);

                for (int i = 0; i < numB; i++)
                {
                    if (i == 0)
                        bannersTimeLine.Add(5);
                    else
                        bannersTimeLine.Add((i * numBDRang) + 5);
                }
            }).Start();
        }

        #endregion

        #region Properties

        private double _mediaVolume;
        public double MediaVolume
        {
            get { return _mediaVolume; }
            set
            {
                _mediaVolume = value;
                RaisePropertyChanged("MediaVolume");
            }
        }

        private string _tagImageSound;
        public string TagImageSound
        {
            get { return _tagImageSound; }
            set
            {
                _tagImageSound = value;
                RaisePropertyChanged("TagImageSound");
            }
        }

        private string _soundImageSource;
        public string SoundImageSource
        {
            get { return _soundImageSource; }
            set
            {
                _soundImageSource = value;
                RaisePropertyChanged("SoundImageSource");
            }
        }

        // Property for 'CircularProgressBar', not in use !!!
        private Visibility _circularProgressBarVisibility;
        public Visibility CircularProgressBarVisibility
        {
            get { return _circularProgressBarVisibility; }
            set
            {
                _circularProgressBarVisibility = value;
                RaisePropertyChanged("CircularProgressBarVisibility");
            }
        }

        private double _mediaHeight;
        public double MediaHeight
        {
            get { return _mediaHeight; }
            set
            { 
                _mediaHeight = value;
                RaisePropertyChanged("MediaHeight");
            }
        }

        private double _mediaWidth;
        public double MediaWidth
        {
            get { return _mediaWidth; }
            set
            { 
                _mediaWidth = value;
                RaisePropertyChanged("MediaWidth");
            }
        }

        private Visibility _bannerVisibility;
        public Visibility BannerVisibility
        {
            get { return _bannerVisibility; }
            set
            {
                _bannerVisibility = value;
               RaisePropertyChanged("BannerVisibility");

               //if(PropertyChanged != null)
               // PropertyChanged(this, new PropertyChangedEventArgs("BannerVisibility"));
            }
        }

        //public new event PropertyChangedEventHandler PropertyChanged;

        private int _bannerHeight;
        public int BannerHeight
        {
            get { return _bannerHeight; }
            set
            {
                switch (value)
                {
                    case 1:
                        _bannerHeight = (int)MediaHeight;
                        break;
                    case 2:
                        _bannerHeight = (int)MediaHeight / 2;
                        break;
                    case 3:
                        _bannerHeight = (int)MediaHeight / 3;
                        break;
                    case 4:
                        _bannerHeight = (int)MediaHeight / 4;
                        break;
                    case 0:
                        _bannerHeight = 0;
                        break;
                }
                RaisePropertyChanged("BannerHeight");
            }
        }

        private string _bannerImage;
        public string BannerImage
        {
            get { return _bannerImage; }
            set
            {
                _bannerImage = value;
                RaisePropertyChanged("BannerImage");
            }
        }

        //private ImageSource _bannerImage;
        //public ImageSource BannerImage
        //{
        //    get { return _bannerImage; }
        //    set
        //    {
        //        _bannerImage = value;
        //        RaisePropertyChanged("BannerImage");
        //    }
        //}

        private string _bannerTitle;
        public string BannerContent
        {
            get { return _bannerTitle; }
            set
            {
                _bannerTitle = value;
                RaisePropertyChanged("BannerContent");
            }
        }

        private string _playPausebuttonContent;
        public string PlayPauseButtonContent
        {
            get { return _playPausebuttonContent; }
            set
            {
                _playPausebuttonContent = value;
                RaisePropertyChanged("PlayPauseButtonContent");
            }
        }

        private string _stopButtonContent;
        public string StopButtonContent
        {
            get { return _stopButtonContent; }
            set
            {
                _stopButtonContent = value;
                RaisePropertyChanged("StopButtonContent");
            }
        }

        // MediaElement Source.
        private string _myVideoPath;
        public string MyVideoPath
        {
            get { return _myVideoPath; }
            set
            {
                _myVideoPath = value;
                RaisePropertyChanged("MyVideoPath");
            }
        }

        private PlayerStatus _videoStatus;
        public PlayerStatus VideoStatus
        {
            get { return _videoStatus; }
            set
            {
                _videoStatus = value;
                RaisePropertyChanged("VideoStatus");
            }
        }

        public string Welcome
        {
            get
            {
                return "Welcome to MVVM Light";
            }
        }

        private List<Thumbnail> thumbnails;
        public List<Thumbnail> Thumbnails
        {
            get { return thumbnails; }
            set
            {
                if (thumbnails != value)
                {
                    thumbnails = value;
                    RaisePropertyChanged("Thumbnails");
                }
            }
        }

        #endregion

        #region Conmmands

        public bool CanCommandExecute { get; set; }
        public RelayCommand<object> SetStatusCommand { get; private set; }
        public RelayCommand<ListViewItem> ImageCommand { get; private set; }
        public RelayCommand<double> HeightCommand { get; set; }
        public RelayCommand<double> WidthCommand { get; set; }
        public RelayCommand<string> SoundImageCommand { get; set; }
        public ICommand OpenDialogBox { get; private set; }

        public void MediaElementHeightChangedCommand(double height)
        {
            MediaHeight = height;
        }

        public void MediaElementWidthChangedCommand(double width)
        {
            MediaWidth = width;
        }

        public void SetSoundImageSource(string tag)
        {
            switch (tag)
            {
                case "1":
                    SoundImageSource = "Images\\Mute.jpg";
                    MediaVolume = 0;
                    TagImageSound = "2";
                    break;
                case "2":
                    SoundImageSource = "Images\\Sound.png";
                    MediaVolume = 0.5;
                    TagImageSound = "1";
                    break;
            }
        }

        public void ShowVideoCommand(ListViewItem id)
        {
            //Mouse.OverrideCursor = Cursors.Wait;
            //CircularProgressBarVisibility = Visibility.Visible;

            Thumbnail tl = id.Content as Thumbnail;

            if (currentVideoId != tl.id)
            {
                currentVideoId = tl.id;
                ThreadPool.QueueUserWorkItem((Action) =>
                {
                    var tmp = proxy.GetVideoById(currentVideoId);
                    ConvertArrayToMyList(tmp.banners);
                    SetSource(tmp.videoUrl);
                    //Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
                    //{
                    //    Mouse.OverrideCursor = null;
                    //}), DispatcherPriority.ApplicationIdle, null);
                });

                PlayPauseButtonContent = "Play";
                //Mouse.OverrideCursor = null;
            }
        }

        #endregion

        #region Internal Functions

        // adjust the curentTimeLine.
        public void CalcTimeLine(double timeStamp)
        {
            for (int i = 0; i < bannersTimeLine.Count; i++)
            {
                if (bannersTimeLine[i] > timeStamp)
                {
                    currentTimeLine = i;
                    break;
                }
            }
        }

        private void SetStatus(object param)
        {
            string action = (string)param;
            switch (action.ToLower())
            {
                case "play":
                    VideoStatus = PlayerStatus.Play;
                    PlayPauseButtonContent = "Pause";
                    StopButtonContent = "Stop";
                    break;
                case "pause":
                    VideoStatus = PlayerStatus.Pause;
                    PlayPauseButtonContent = "Play";
                    break;
                case "stop":
                    VideoStatus = PlayerStatus.Stop;
                    PlayPauseButtonContent = "Play";
                    StopButtonContent = "";
                    currentTimeLine = 0;
                    break;
            }
        }

        private void openDlg()
        {
            var tmp = proxy.GetVideoById(4);
            //SetSource(tmp.videoByte);
            SetSource(tmp.videoUrl);
        }

        private void GetAllVideoThumbnails()
        {
            var arr = proxy.GetAllThumbnailVideoAvailable().ListViewItems;
            List<Thumbnail> tmp = new List<Thumbnail>();
            foreach (var item in arr)
            {
                //Image tmpImage = new Image();
                //tmpImage.Source = GetBitmapImage(item.smallImageByte);
                tmp.Add(new Thumbnail() { id = item.id, imageUrl = item.imageUrl, name = item.name });
                //{ id = item.id, image = tmpImage, name = item.name });
            }
            Thumbnails = tmp;
        }

        // convert byte[] to mediaElement Source
        private void SetSource(string url)//(byte[] videoBytes)
        {
            VideoStatus = PlayerStatus.Stop;
            //CircularProgressBarVisibility = Visibility.Visible;
            MyVideoPath = url;
            //MyVideoPath = null;
            //FileStream fs = null;

            //if (File.Exists(Environment.CurrentDirectory + "\\" + "video.wmv"))
            //{
            //    File.Delete(Environment.CurrentDirectory + "\\" + "video.wmv");
            //    using (fs = new FileStream(Environment.CurrentDirectory + "\\" + "video1.wmv", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            //    {
            //        fs.Write(videoBytes, 0, videoBytes.Length);
            //    }
            //    MyVideoPath = Environment.CurrentDirectory + "\\" + "video1.wmv";
            //}
            //else
            //{
            //    File.Delete(Environment.CurrentDirectory + "\\" + "video1.wmv");
            //    using (fs = new FileStream(Environment.CurrentDirectory + "\\" + "video.wmv", FileMode.OpenOrCreate, FileAccess.ReadWrite))
            //    {
            //        fs.Write(videoBytes, 0, videoBytes.Length);
            //    }
            //    MyVideoPath = Environment.CurrentDirectory + "\\" + "video.wmv";
            //}
            InitializeAllProperties();
        }

        private void InitializeAllProperties()
        {
            PlayPauseButtonContent = "Play";
            BannerContent = "";
            BannerImage = null;
            BannerHeight = 0;
            //CircularProgressBarVisibility = Visibility.Hidden;
            //Mouse.OverrideCursor = null;
        }

        // Convert byte[] to bitmapImage
        private BitmapImage GetBitmapImage(byte[] imageBytes)
        {
            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.StreamSource = new MemoryStream(imageBytes);
            bitmapImage.EndInit();
            return bitmapImage;
        }

        // convert DB BannerClass[] arr to List. 
        private void ConvertArrayToMyList(MyBannerClass[] arr)//(BannerClass[] arr)
        {
            banners.Clear();
            foreach (var ban in arr)
            {
                banners.Add(ban);
            }
        }

        #endregion
    }

    public class Thumbnail
    {
        public int id { get; set; }
        //public Image image { get; set; }
        public string imageUrl { get; set; } 
        public string name { get; set; }
    }

    public class MediaElementCom : ICommand
    {
        private MainViewModel vm;

        public MediaElementCom(MainViewModel vm)
        {
            this.vm = vm;
        }
    
        #region ICommand Members

        public bool  CanExecute(object parameter)
        {
            return vm.CanCommandExecute;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void  Execute(object parameter)
        {
            string action = (string)parameter;
            switch (action.ToLower())
            {
                //case "play":
                //    vm.MediaElementProp.Play();
                //    break;
                //case "pause":
                //    vm.MediaElementProp.Pause();
                //    break;
                //case "stop":
                //    vm.MediaElement.Stop();
                //    break;
                //case "backward":
                //    vm.MediaElement.Position = vm.MediaElement.Position - TimeSpan.FromSeconds(10);
                //    break;
                //case "forward":
                //    vm.MediaElement.Position = vm.MediaElement.Position + TimeSpan.FromSeconds(10);
                //    break;
            }
        }

        #endregion
}
}